package com.linked.scheduledtasks.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.linked.universal.linkedutil.RedisKeyRondomTime;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author :dbq
 * @date : 2023/2/22 10:27
 * @description : desc
 */
@Component
@Slf4j
public class HandleRedisUtils<R> {

    private RedisTemplate redisTemplate;

    private ObjectMapper mapper;

    @Autowired
    public HandleRedisUtils(RedisTemplate redisTemplate, ObjectMapper mapper) {
        this.redisTemplate = redisTemplate;
        this.mapper = mapper;
    }

    public boolean removeKey(String redisKey) {
        if (redisTemplate.hasKey(redisKey)) {
            return redisTemplate.delete(redisKey);
        } else {
            return true;
        }
    }

    /**
     * 根据key查询redis,如果redis中没有key,则去数据库中获取，获取成功后，存入redis中
     */
    public List<R> getRedisValueList(String redisKey, Function method, R param) throws Exception {
        List<R> redisValueList = null;
        if (redisTemplate.hasKey(redisKey)) {
            String value_json = (String) redisTemplate.opsForValue().get(redisKey);
            redisValueList = mapper.readValue(value_json, new TypeReference<List<R>>() {
            });
        } else {
            //执行参数中得方法
            redisValueList = (List<R>) method.apply(param);
            //把查询到的结果，放入到redis中
            if (!CollectionUtils.isEmpty(redisValueList)) {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValueList));
            } else {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValueList), 60, TimeUnit.SECONDS);
            }
        }
        return redisValueList;
    }

    public List<R> getRedisValueList(String redisKey, Supplier method) throws Exception {
        List<R> redisValueList = null;
        if (redisTemplate.hasKey(redisKey)) {
            String value_json = (String) redisTemplate.opsForValue().get(redisKey);
            redisValueList = mapper.readValue(value_json, new TypeReference<List<R>>() {
            });
        } else {
            //执行参数中得方法
            redisValueList = (List<R>) method.get();
            //把查询到的结果，放入到redis中
            if (!CollectionUtils.isEmpty(redisValueList)) {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValueList));
            } else {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValueList), 60, TimeUnit.SECONDS);
            }
        }
        return redisValueList;
    }

    public List<R> getRedisValueList(String redisKey, Function method, Object param, Long timeOut, TimeUnit timeUnit) throws Exception {
        List<R> redisValueList = null;
        if (redisTemplate.hasKey(redisKey)) {
            String value_json = (String) redisTemplate.opsForValue().get(redisKey);
            redisValueList = mapper.readValue(value_json, new TypeReference<List<R>>() {
            });
        } else {
            //执行参数中得方法
            redisValueList = (List<R>) method.apply(param);
            //把查询到的结果，放入到redis中
            if (!CollectionUtils.isEmpty(redisValueList)) {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValueList), timeOut + RedisKeyRondomTime.getExtraTime(timeUnit), timeUnit);
            } else {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValueList), timeOut, timeUnit);
            }
        }
        return redisValueList;
    }

    public R getRedisValue(String redisKey, Function method, Object param) throws Exception {
        R redisValue = null;
        if (redisTemplate.hasKey(redisKey)) {
            String value_json = (String) redisTemplate.opsForValue().get(redisKey);
            redisValue = mapper.readValue(value_json, new TypeReference<R>() {
            });
        } else {
            //执行参数中得方法
            redisValue = (R) method.apply(param);
            //把查询到的结果，放入到redis中
            if (redisValue != null) {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValue));
            } else {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValue), 60, TimeUnit.SECONDS);
            }
        }
        return redisValue;
    }

    public R getRedisValue(String redisKey, Function method, Object param, Long timeOut, TimeUnit timeUnit) throws Exception {
        R redisValue = null;
        if (redisTemplate.hasKey(redisKey)) {
            String value_json = (String) redisTemplate.opsForValue().get(redisKey);
            redisValue = mapper.readValue(value_json, new TypeReference<R>() {
            });
        } else {
            //执行参数中得方法
            redisValue = (R) method.apply(param);
            //把查询到的结果，放入到redis中
            if (redisValue != null) {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValue), timeOut + RedisKeyRondomTime.getExtraTime(timeUnit), timeUnit);
            } else {
                redisTemplate.opsForValue().set(redisKey, mapper.writeValueAsString(redisValue), timeOut, timeUnit);
            }
        }
        return redisValue;
    }

}
